<template>
  <div class="field-controller">
    <el-card class="form-card">
      <template #header>
        <div class="field-controller-header">
          <div class="title-section">
            <h3>字段控制器</h3>
            <el-checkbox v-model="hideUnconfigured" @change="onFilterChange">
              忽略无配置
            </el-checkbox>
            <el-checkbox v-model="hideHiddenFields" @change="onFilterChange">
              忽略隐藏
            </el-checkbox>
          </div>
          <div class="button-section">
            <el-button
              type="success"
              size="small"
              @click="addDescriptionsToLeafNodes"
              :loading="isAddingDescriptions"
              class="add-descriptions-btn"
            >
              添加字段描述
            </el-button>
            <el-button
              type="warning"
              size="small"
              @click="propagateFieldDependency"
              :loading="isPropagatingDependency"
              class="propagate-dependency-btn"
            >
              传播字段依赖
            </el-button>
          </div>
        </div>
      </template>
      <div class="tree-scroll">
        <el-tree
          ref="treeRef"
          :data="filteredTreeData"
          :props="defaultProps"
          node-key="id"
          :expand-on-click-node="false"
          :check-on-click-node="false"
          :default-expand-all="false"
        >
          <template #default="{ data }">
            <div class="custom-tree-node">
              <div class="field-label-section">
                <span class="field-label">{{ data.label }}</span>
                <div class="display-name-section">
                  <span 
                    v-if="!data.editingDisplayName" 
                    class="display-name"
                    @click="startEditDisplayName(data)"
                    :title="'点击编辑展示名称'"
                  >
                    {{ data.display_name || data.label }}
                  </span>
                  <el-tooltip
                    v-if="!data.editingDisplayName && data.description"
                    :content="data.description"
                    placement="top"
                    :show-after="300"
                  >
                    <el-icon class="description-icon">
                      <InfoFilled />
                    </el-icon>
                  </el-tooltip>
                  <el-input
                    v-else-if="data.editingDisplayName"
                    v-model="data.display_name"
                    size="small"
                    class="display-name-input"
                    placeholder="输入展示名称"
                    @blur="finishEditDisplayName(data)"
                    @keyup.enter="finishEditDisplayName(data)"
                    @keyup.esc="cancelEditDisplayName(data)"
                    @click.stop
                  />
                </div>
              </div>
              <div class="node-controls-card" @click.stop>
                <el-tag
                  :type="data.x_descriptor_count > 0 ? 'success' : 'info'"
                  size="small"
                >
                  {{ data.x_descriptor_count }}
                </el-tag>
                <el-tag
                  v-if="data.children_descriptor_count > 0"
                  type="info"
                  size="small"
                  class="children-counter"
                >
                  ↓{{ data.children_descriptor_count }}
                </el-tag>
                <el-button
                  :type="data.hidden ? 'danger' : 'info'"
                  size="small"
                  @click.stop="toggleHidden(data)"
                  :title="data.hidden ? '点击显示字段' : '点击隐藏字段'"
                  circle
                >
                  <el-icon>
                    <Close v-if="data.hidden" />
                    <View v-else />
                  </el-icon>
                </el-button>
                <el-button
                  type="primary"
                  size="small"
                  @click.stop="openDescriptorDialog(data)"
                >
                  编辑描述符
                </el-button>
              </div>
            </div>
          </template>
        </el-tree>
      </div>
    </el-card>

    <el-dialog
      v-model="dialogVisible"
      title="编辑描述符"
      width="60%"
      :append-to-body="true"
      :destroy-on-close="true"
    >
      <descriptor-editor
        v-if="dialogVisible && selectedField"
        :field="selectedField"
        @save="handleSaveDescriptor"
        @cancel="dialogVisible = false"
        @sync-field-group="handleSyncFieldGroup"
      />
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, nextTick, type Ref } from 'vue'
import { invoke } from '@tauri-apps/api/core'
import { ElMessage } from 'element-plus'
import DescriptorEditor from './DescriptorEditor.vue'
import { InfoFilled, Close, View } from '@element-plus/icons-vue'

// 定义 props 类型
interface FieldData {
  id: string
  label: string
  display_name: string
  hidden: boolean
  x_descriptors: string[]
  x_descriptor_count: number
  children_descriptor_count: number
  path?: string
  children?: FieldData[]
  editingDisplayName?: boolean
  originalDisplayName?: string
  description?: string
}

interface Props {
  treeData: FieldData[]
}

const props = defineProps<Props>()

// 定义 emits
const emit = defineEmits<{
  updateFields: [treeData: FieldData[]]
  syncToDescriptor: []
}>()

// 树形控件的配置
const defaultProps = {
  children: 'children',
  label: 'label'
}

// 响应式数据
const dialogVisible: Ref<boolean> = ref(false)
const selectedField: Ref<FieldData | null> = ref(null)
const hideUnconfigured: Ref<boolean> = ref(false)
const hideHiddenFields: Ref<boolean> = ref(false)
const isAddingDescriptions: Ref<boolean> = ref(false)
const isPropagatingDependency: Ref<boolean> = ref(false)
const treeRef = ref<any>(null)

// 递归检查字段或其子字段是否有配置
const hasConfiguration = (field: FieldData): boolean => {
  // 如果字段本身有描述符配置，返回true
  if (field.x_descriptor_count > 0) {
    return true
  }
  
  // 递归检查子字段
  if (field.children && field.children.length > 0) {
    return field.children.some(child => hasConfiguration(child))
  }
  
  return false
}

// 检查字段本身是否有隐藏描述符（不递归检查子字段）
const hasHiddenDescriptor = (field: FieldData): boolean => {
  const hiddenDescriptor = 'urn:alm:descriptor:com.tectonic.ui:hidden'
  
  // 只检查字段本身是否有隐藏描述符，不递归检查子字段
  return field.x_descriptors && field.x_descriptors.includes(hiddenDescriptor)
}

// 递归过滤树数据
const filterTreeData = (data: FieldData[]): FieldData[] => {
  return data.filter(field => {
    let shouldShow = true
    
    // 检查是否需要隐藏无配置的字段
    if (hideUnconfigured.value) {
      shouldShow = shouldShow && hasConfiguration(field)
    }
    
    // 检查是否需要隐藏带有隐藏描述符的字段
    if (hideHiddenFields.value) {
      shouldShow = shouldShow && !hasHiddenDescriptor(field)
    }
    
    // 如果字段需要显示，过滤其子字段
    if (shouldShow && field.children) {
      field.children = filterTreeData(field.children)
    }
    
    return shouldShow
  })
}

// 计算属性：过滤后的树数据
const filteredTreeData = computed(() => {
  return filterTreeData([...props.treeData])
})

// 切换隐藏状态
const toggleHidden = async (data: FieldData): Promise<void> => {
  data.hidden = !data.hidden
  await handleHiddenChange(data)
}

// 处理隐藏状态变化
const handleHiddenChange = async (data: FieldData): Promise<void> => {
  console.log('隐藏状态变化:', data.id, '新状态:', data.hidden)
  
  const hiddenDescriptor = 'urn:alm:descriptor:com.tectonic.ui:hidden'
  
  if (data.hidden) {
    if (!data.x_descriptors.includes(hiddenDescriptor)) {
      data.x_descriptors.push(hiddenDescriptor)
      data.x_descriptor_count = data.x_descriptors.length
    }
  } else {
    const index = data.x_descriptors.indexOf(hiddenDescriptor)
    if (index > -1) {
      data.x_descriptors.splice(index, 1)
      data.x_descriptor_count = data.x_descriptors.length
    }
  }
  
  console.log('隐藏状态更新完成:', data.x_descriptors)
  
  try {
    // 更新子字段统计
    const result = await invoke('update_children_descriptor_counts', {
      treeData: props.treeData
    }) as FieldData[]
    
    console.log('发出updateFields事件，数据:', result)
    // 发出事件让父组件处理
    emit('updateFields', result)
    // 自动触发同步到Descriptor
    emit('syncToDescriptor')
    
    console.log('子字段统计更新完成')
  } catch (error) {
    console.error('更新子字段统计失败:', error)
    // 如果统计更新失败，仍然发出原始数据的更新事件
    nextTick(() => {
      emit('updateFields', [...props.treeData])
      // 即使更新失败也要触发同步
      emit('syncToDescriptor')
    })
  }
}

// 打开描述符编辑对话框
const openDescriptorDialog = (field: FieldData): void => {
  console.log('打开描述符编辑对话框:', field)
  
  // 确保字段有正确的路径信息
  if (!field.path) {
    field.path = field.id || field.label
  }
  
  selectedField.value = field
  dialogVisible.value = true
  console.log('对话框状态:', dialogVisible.value, '选中字段:', selectedField.value)
}

// 处理保存描述符
const handleSaveDescriptor = async (updatedField: FieldData): Promise<void> => {
  if (selectedField.value) {
    Object.assign(selectedField.value, updatedField)
  }
  dialogVisible.value = false
  
  try {
    // 更新子字段统计
    const result = await invoke('update_children_descriptor_counts', {
      treeData: props.treeData
    }) as FieldData[]
    
    // 发出事件让父组件处理
    emit('updateFields', result)
    // 自动触发同步到Descriptor
    emit('syncToDescriptor')
    
    console.log('保存描述符完成，更新后的字段数据:', updatedField)
  } catch (error) {
    console.error('更新子字段统计失败:', error)
    // 如果统计更新失败，仍然发出原始数据的更新事件
    emit('updateFields', props.treeData)
    // 即使更新失败也要触发同步
    emit('syncToDescriptor')
  }
}

// 处理字段组同步
const handleSyncFieldGroup = (_fieldPath: string, action: 'add' | 'remove'): void => {
  if (!selectedField.value) return
  
  const currentField = selectedField.value
  const fieldGroupDescriptor = `urn:alm:descriptor:com.tectonic.ui:fieldGroup:${currentField.label}`
  
  // 递归更新子字段
  const updateChildren = (children: FieldData[] | undefined) => {
    if (!children) return
    
    children.forEach(child => {
      if (child.x_descriptors.length > 0) { // 只为已有描述符的子字段添加
        if (action === 'add') {
          // 移除所有现有的 fieldGroup 描述符
          child.x_descriptors = child.x_descriptors.filter(desc => 
            !desc.startsWith('urn:alm:descriptor:com.tectonic.ui:fieldGroup')
          )
          // 添加新的 fieldGroup 描述符
          child.x_descriptors.push(fieldGroupDescriptor)
          child.x_descriptor_count = child.x_descriptors.length
        } else if (action === 'remove') {
          const index = child.x_descriptors.indexOf(fieldGroupDescriptor)
          if (index > -1) {
            child.x_descriptors.splice(index, 1)
            child.x_descriptor_count = child.x_descriptors.length
          }
        }
      }
      
      // 递归处理子节点的子节点
      updateChildren(child.children)
    })
  }
  
  updateChildren(currentField.children)
}

// 添加描述符到叶子节点
const addDescriptionsToLeafNodes = async (): Promise<void> => {
  try {
    isAddingDescriptions.value = true
    
    // 调用后端方法处理树数据
    const result = await invoke('add_descriptions_to_leaf_nodes', {
      treeData: props.treeData
    }) as FieldData[]
    
    // 更新树数据，通知父组件
    emit('updateFields', result)
    // 触发同步到Descriptor
    emit('syncToDescriptor')
    console.log('处理结果:', result)
  } catch (error) {
    console.error('添加描述符失败:', error)
    ElMessage.error('添加描述符失败: ' + error)
  } finally {
    isAddingDescriptions.value = false
  }
}

// 开始编辑展示名称
const startEditDisplayName = (field: FieldData): void => {
  field.originalDisplayName = field.display_name || field.label
  field.editingDisplayName = true
  nextTick(() => {
    const input = document.querySelector('.display-name-input input') as HTMLInputElement
    if (input) {
      input.focus()
      input.select()
    }
  })
}

// 完成编辑展示名称
const finishEditDisplayName = async (field: FieldData): Promise<void> => {
  field.editingDisplayName = false
  const newDisplayName = field.display_name || field.label
  delete field.originalDisplayName
  
  // 如果displayName为空，设置为label
  if (!field.display_name || field.display_name.trim() === '') {
    field.display_name = field.label
  }
  
  console.log('展示名称编辑完成:', field.label, '->', field.display_name)
  
  // 使用专门的后端命令更新字段的display_name
  try {
    const fieldPath = field.id || field.label
    const result = await invoke('update_field_display_name', {
      treeData: props.treeData,
      fieldPath: fieldPath,
      newDisplayName: newDisplayName
    }) as FieldData[]
    
    emit('updateFields', result)
    // 自动触发同步到Descriptor
    emit('syncToDescriptor')
    
    console.log('展示名称更新完成')
  } catch (error) {
    console.error('更新展示名称失败:', error)
    // 如果后端更新失败，回退到之前的逻辑
    try {
      const result = await invoke('update_children_descriptor_counts', {
        treeData: props.treeData
      }) as FieldData[]
      
      emit('updateFields', result)
      // 自动触发同步到Descriptor
      emit('syncToDescriptor')
    } catch (fallbackError) {
      console.error('回退更新也失败:', fallbackError)
    }
  }
}

// 取消编辑展示名称
const cancelEditDisplayName = (field: FieldData): void => {
  if (field.originalDisplayName !== undefined) {
    field.display_name = field.originalDisplayName
  }
  field.editingDisplayName = false
  delete field.originalDisplayName
}

// 处理过滤条件变化
const onFilterChange = (): void => {
  // 这里可以根据需要添加过滤逻辑
  console.log('过滤条件变化:', hideUnconfigured.value, hideHiddenFields.value)
}

// 处理传播字段依赖
const propagateFieldDependency = async (): Promise<void> => {
  try {
    isPropagatingDependency.value = true
    
    // 由于后端命令一次只能处理一个树节点，需要为每个根节点调用
    const updatedTreeData = []
    
    for (const treeNode of props.treeData) {
      const result = await invoke('propagate_field_dependency', {
        treeData: JSON.stringify(treeNode)
      }) as string
      
      const updatedNode = JSON.parse(result) as FieldData
      updatedTreeData.push(updatedNode)
    }
    
    // 更新树数据，通知父组件
    emit('updateFields', updatedTreeData)
    // 自动触发同步到Descriptor
    emit('syncToDescriptor')
    console.log('传播字段依赖完成:', updatedTreeData)
    
    ElMessage.success('成功传播字段依赖')
  } catch (error) {
    console.error('传播字段依赖失败:', error)
    ElMessage.error('传播字段依赖失败: ' + error)
  } finally {
    isPropagatingDependency.value = false
  }
}
</script>

<style lang="scss" scoped>
.field-controller {
  height: 100%;
  
  .form-card {
    height: 100%;
    box-shadow: 0 2px 8px rgba(0,0,0,0.06);
    border-radius: 10px;
    
    .field-controller-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      font-size: 18px;
      font-weight: 600;
      padding: 8px 0;
      
      .title-section {
        display: flex;
        align-items: center;
        gap: 12px;
        
        h3 {
          margin: 0;
        }
        
        .el-checkbox {
          margin-left: 8px;
          
          &:not(:last-child) {
            margin-right: 16px;
          }
        }
      }
      
      .button-section {
        display: flex;
        align-items: center;
        gap: 12px;
        
        .add-descriptions-btn {
          font-size: 12px;
          padding: 6px 12px;
          border-radius: 6px;
          height: 28px;
          font-weight: 500;
          border: none;
          box-shadow: 0 1px 2px rgba(103, 194, 58, 0.2);
          
          &:hover {
            transform: translateY(-1px);
            box-shadow: 0 2px 6px rgba(103, 194, 58, 0.3);
          }
          
          &:active {
            transform: translateY(0);
          }
        }
        
        .propagate-dependency-btn {
          font-size: 12px;
          padding: 6px 12px;
          border-radius: 6px;
          height: 28px;
          font-weight: 500;
          border: none;
          box-shadow: 0 1px 2px rgba(230, 162, 60, 0.2);
          
          &:hover {
            transform: translateY(-1px);
            box-shadow: 0 2px 6px rgba(230, 162, 60, 0.3);
          }
          
          &:active {
            transform: translateY(0);
          }
        }
      }
    }
  }
  
  .tree-scroll {
    max-height: calc(100vh - 180px);
    min-height: 300px;
    overflow-y: auto;
    padding: 12px;
    background: #fafbfc;
    border-radius: 8px;
    
    // 性能优化
    contain: layout style paint;
    will-change: scroll-position;
    
    // 重置Element Plus树形组件的默认样式
    :deep(.el-tree) {
      background: transparent;
      
      .el-tree-node {
        margin-bottom: 8px;
        
        &:focus > .el-tree-node__content {
          background-color: transparent;
        }
        
        .el-tree-node__content {
          background: transparent;
          border-radius: 8px;
          padding: 0;
          height: auto;
          min-height: 50px;
          
          &:hover {
            background: transparent;
          }
        }
        
        .el-tree-node__expand-icon {
          padding: 8px;
          color: #409eff;
          border-radius: 50%;
          transition: all 0.3s ease;
          
          &:hover {
            background: var(--el-color-primary-light-9);
            color: var(--el-color-primary);
            transform: scale(1.1);
          }
          
          &.is-leaf {
            color: transparent;
            cursor: default;
            
            &:hover {
              background: transparent;
              transform: none;
            }
          }
        }
      }
    }
  }
  
  .custom-tree-node {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 16px;
    background: #ffffff;
    border-radius: 10px;
    border: 1px solid #e4e7ed;
    position: relative;
    transition: all 0.3s ease;
    box-shadow: 0 1px 3px rgba(0,0,0,0.02);
    
    .field-label-section {
      display: flex;
      align-items: center;
      gap: 8px;
      flex: 1;
      margin-right: 16px;
      min-width: 0;
    }
    
    .field-label {
      font-weight: 600;
      color: #303133;
      font-size: 15px;
      letter-spacing: 0.3px;
      word-break: break-word;
      transition: color 0.3s ease;
    }
    
    .display-name-section {
      display: flex;
      align-items: center;
      gap: 8px;
      flex: 1;
      min-width: 0;
    }
    
    .display-name {
      font-weight: 400;
      color: #C0C4CC;
      font-size: 13px;
      letter-spacing: 0.2px;
      word-break: break-word;
      opacity: 0.8;
      cursor: pointer;
      padding: 2px 6px;
      border-radius: 4px;
      transition: all 0.3s ease;
      border: 1px solid transparent;
      
      &:hover {
        background-color: #f5f7fa;
        color: #606266;
        border-color: #e4e7ed;
      }
    }
    
    .display-name-input {
      flex: 1;
      
      :deep(.el-input__wrapper) {
        font-size: 13px;
        font-weight: 400;
        background: #f5f7fa;
        border: 1px solid #409eff;
        border-radius: 4px;
        box-shadow: 0 0 0 1px rgba(64, 158, 255, 0.2);
        padding: 2px 8px;
      }
    }
    
    .description-icon {
      font-size: 14px;
      color: #909399;
      margin-left: 4px;
      cursor: help;
      transition: color 0.3s ease;
      
      &:hover {
        color: #409eff;
      }
    }
    
    .node-controls-card {
      display: flex;
      align-items: center;
      gap: 12px;
      flex-shrink: 0; // 防止控制区域被压缩
      background: #f8f9fa;
      border-radius: 12px;
      padding: 6px 14px;
      border: 1px solid #e9ecef;
      transition: all 0.3s ease;
      
      .el-tag {
        min-width: 32px;
        text-align: center;
        font-size: 12px;
        font-weight: 600;
        height: 24px;
        line-height: 22px;
        border-radius: 6px;
        font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
        
        &[class*="el-tag--success"] {
          background-color: #67c23a;
          border-color: #67c23a;
          color: white;
        }
        
        &[class*="el-tag--info"] {
          background-color: #909399;
          border-color: #909399;
          color: white;
        }
        
        &.children-counter {
          background-color: #00B7EB;
          border-color: #00B7EB;
          color: white;
          font-size: 11px;
          padding: 0 6px;
          min-width: auto;
          font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
          font-weight: 700;
        }
      }
      
      .el-checkbox {
        margin: 0;
        
        :deep(.el-checkbox__input) {
          .el-checkbox__inner {
            width: 16px;
            height: 16px;
            border-radius: 4px;
            
            &:after {
              width: 4px;
              height: 8px;
              left: 5px;
              top: 1px;
            }
          }
        }
      }
      
      .el-button {
        font-size: 12px;
        padding: 6px 12px;
        border-radius: 6px;
        height: 28px;
        font-weight: 500;
        border: none;
        box-shadow: 0 1px 2px rgba(64, 158, 255, 0.2);
        
        &:hover {
          transform: translateY(-1px);
          box-shadow: 0 2px 6px rgba(64, 158, 255, 0.3);
        }
        
        &:active {
          transform: translateY(0);
        }
      }
    }
    
    // 性能优化
    contain: layout;
    transform: translateZ(0); // 启用硬件加速
    
    // hover效果
    &:hover {
      background: #ffffff;
      border-color: #c0c4cc;
      box-shadow: 0 4px 12px rgba(0,0,0,0.08);
      transform: translateY(-2px) translateZ(0);
      
      .field-label {
        color: #409eff;
      }
      
      .node-controls-card {
        background: #f0f9ff;
        border-color: #d1e7ff;
        box-shadow: 0 2px 8px rgba(64, 158, 255, 0.1);
      }
    }
    
    // 激活状态
    &:active {
      transform: translateY(-1px) translateZ(0);
      box-shadow: 0 2px 8px rgba(0,0,0,0.06);
    }
  }
}

// 全局修复Element Plus组件的z-index问题
:deep(.el-popper) {
  z-index: 3000 !important;
}

:deep(.el-dialog) {
  z-index: 3100 !important;
}

:deep(.el-overlay) {
  z-index: 3050 !important;
}
</style> 